home *** CD-ROM | disk | FTP | other *** search
/ Complete Linux / Complete Linux.iso / docs / apps / database / postgres / postgre2.z / postgre2 / doc / manual.me < prev    next >
Encoding:
Text File  |  1992-08-27  |  69.0 KB  |  2,816 lines

  1. .\".he '\*(dA'DRAFT'\*(tI'        \" comment out in production version
  2. .\"========================================================
  3. .\"------------------------------------
  4. .\" /home1/frew/s2k/postgres/manual/RCS/manual.me,v 1.10 1992/07/07 17:44:44 frew Exp
  5. .\"------------------------------------
  6. .\" XXX standard disclaimer belongs here....
  7. .\"---------------------------------------------------------------------------
  8. .de cW                    \" arg3arg1arg2, constant-width arg1
  9. \&\\$3\\fC\\$1\\fP\\$2
  10. .\"\&\\$3\\fC\\s-1\\$1\\s0\\fP\\$2
  11. ..
  12. .\"------------------------------------
  13. .de xP                    \" ip for references
  14. .ip \\$1 \\w'[STON90B]'u+2n
  15. ..
  16. .\"------------------------------------
  17. .de (P                    \" prologue for constant-width block
  18. .ft C
  19. .ps -1
  20. .vs -1
  21. ..
  22. .\"-----------------
  23. .de )P                    \" epilogue for constant-width block
  24. .vs +1
  25. .ps +1
  26. .ft P
  27. ..
  28. .\"------------------------------------
  29. .de (T                    \" prologue for constant-width table
  30. .(P
  31. .in +\\n(biu
  32. ..
  33. .\"-----------------
  34. .de )T                    \" epilogue for constant-width table
  35. .in -\\n(biu
  36. .)P
  37. ..
  38. .\"------------------------------------
  39. .de (C                    \" begin constant-width list
  40. .(l
  41. .(P
  42. ..
  43. .\"-----------------
  44. .de )C                    \" end constant-width list
  45. .)P
  46. .)l
  47. ..
  48. .\"---------------------------------------------------------------------------
  49. .    ds II \s-1INGRES\s0
  50. .    ds PP \s-1POSTGRES\s0
  51. .    ds UU \s-1UNIX\s0
  52. .    ds PQ \s-1POSTQUEL\s0
  53. .    ds LP \s-1LIBPQ\s0
  54. .    ds PV \s-14.0\s0
  55. .    ds OF \s-1PICASSO\s0
  56. .\"------------------------------------
  57. .ps 11
  58. .vs 13
  59. .\"-----------------
  60. .nr pp \n(.s
  61. .nr sp \n(.s+1                \" +1-pt section headers
  62. .\"-----------------
  63. .nr bs 1v
  64. .nr ps 0.3v
  65. .nr ss 1v
  66. .\"-----------------
  67. .fo ''\\s+2%\\s0''            \" +2-pt page numbers in center footers
  68. .\"-----------------
  69. .nr $i .5i                \" main text indented
  70. .nr so -\n($i                \" section headers un-indented
  71. .\"------------------------------------
  72. .rm xX                    \" scratch register
  73. .\"------------------------------------
  74. .\"!Gexpand
  75. .\"---------------------------------------------------------------------------
  76. .(l C
  77. .b
  78. \s+3The \*(PP User Manual\s0
  79. .sp 2
  80. .i
  81. Edited by Jon Rhein, Greg Kemnitz and The \*(PP Group
  82. EECS Dept.
  83. University of California, Berkeley
  84. .r
  85. .)l
  86. .sp 3
  87. .\"---------------------------------------------------------------------------
  88. .sh 1 "OVERVIEW"
  89. .lp
  90. This document is the user manual for the \*(PP database
  91. system under development at the University of California,
  92. Berkeley.
  93. This project, led by Professor Michael Stonebraker, is
  94. sponsored by the Defense Advanced Research Projects Agency
  95. (DARPA), the Army Research Office (ARO), the National Science
  96. Foundation (NSF), and ESL, Inc.
  97. .\"------------------------------------
  98. .sh 2 "DISTRIBUTION"
  99. .lp
  100. This manual describes Version \*(PV of \*(PP.
  101. The \*(PP Group has compiled and tested Version \*(PV on the following
  102. platforms:
  103. .TS
  104. center tab(|);
  105. c | c
  106. l | l .
  107. architecture|operating system
  108. =
  109. DECstation (MIPS)|ULTRIX V4.2
  110. SPARC|SunOS 4.1.2
  111. Sequent Symmetry (386)|DYNIX V3.0
  112. .TE
  113. .\"------------------------------------
  114. .sh 2 "PERFORMANCE"
  115. .lp
  116. Version \*(PV has been tuned modestly.
  117. On the
  118. Wisconsin benchmark, one should expect performance about twice
  119. that of the public domain, University of California version of
  120. \*(II, a relational prototype from the late 1970's.
  121. .\"------------------------------------
  122. .sh 2 "ACKNOWLEDGEMENTS"
  123. .lp
  124. \*(PP has been constructed by a team of undergraduate,
  125. graduate, and staff programmers.
  126. The contributors (in
  127. alphabetical order) consisted of James Bell, Jennifer Caetta, Jolly Chen,
  128. Ron Choi, Jeffrey Goh, Joey Hellerstein, Wei Hong,
  129. Anant Jhingran, Greg Kemnitz, Case Larsen, Jeff Meredith, Michael Olson,
  130. Lay-Peng Ong, Spyros Potamianos, Sunita Sarawagi and Cimarron Taylor.
  131. .lp
  132. For version \*(PV Jeff Meredith served as chief programmer and was
  133. responsible for overall coordination of the project and for individually
  134. implementing the
  135. .q "everything else"
  136. portion of the system.
  137. .lp
  138. The above implementation team contributed significantly to
  139. this manual, as did Claire Mosher, Chandra Ghosh, and Jim Frew.
  140. .\"---------------------------------------------------------------------------
  141. .sh 1 "INTRODUCTION"
  142. .lp
  143. Traditional relational DBMSs support a data model consisting
  144. of a collection of named relations, each attribute of which has a
  145. specific type.
  146. In current commercial systems, possible types are
  147. floating point numbers, integers, character strings, money, and
  148. dates.
  149. It is commonly recognized that this model is inadequate
  150. for future data processing applications.
  151. .lp
  152. The relational model succeeded in
  153. replacing previous models in part because of its simplicity.
  154. The \*(PP data model offers substantial
  155. additional power by incorporating the following four additional basic
  156. constructs:
  157. .(l
  158. classes
  159. inheritance
  160. types
  161. functions
  162. .)l
  163. The \*(PP DBMS has been under construction since 1986.
  164. The initial concepts for the system were presented in [STON86]
  165. and the initial data model appeared in [ROWE87].
  166. The first rule
  167. system that was implemented is discussed in [STON88] and the
  168. storage manager concepts are detailed in [STON87].
  169. The first
  170. .q demo-ware
  171. was operational in 1987, and we released Version 1 of
  172. \*(PP to a few external users in June 1989.
  173. A critique of
  174. version 1 of \*(PP appears in [STON90].
  175. Version 2 followed in
  176. June 1990, and it included a new rule system documented in
  177. [STON90B].
  178. Version \*(PV, the current version of \*(PP,
  179. is about 200,000 lines of code in the C programming language.
  180. \*(PP is available free of charge, and is being used by approximately
  181. 200 sites around the world at this writing.
  182. .\"---------------------------------------------------------------------------
  183. .sh 1 "ORGANIZATION"
  184. .lp
  185. This manual discusses the \*(PQ query language, including extensions such
  186. as user-defined types, operators, and both query language and programming
  187. language functions.
  188. Arrays of types and functions of an instance are
  189. discussed, as well as the \*(PP rule system.
  190. This manual concludes with
  191. a discussion on adding an operator class to \*(PP for use in access methods.
  192. .lp
  193. This manual describes the major
  194. concepts of the system
  195. and attempts to provide an accessible path into using the system.
  196. As such, it tries to give examples of the use of the major
  197. constructs, so a beginning user does not need to delve
  198. immediately into the Reference Manual.
  199. .\"---------------------------------------------------------------------------
  200. .sh 1 "WHAT YOU SHOULD READ"
  201. .lp
  202. This manual is primarily intended to provide a broad overview of the system,
  203. as well as to illustrate how programmers would use functions to interact with
  204. the \*(PP
  205. .q backend.
  206. The \*(PP Reference Manual discusses additional aspects
  207. of
  208. the system, and provides full syntactic descriptions of every \*(PP and \*(PQ
  209. command in a format similar to that used in \*(UU
  210. .q "man pages."
  211. .lp
  212. If you are new to \*(PP, you should probably read this manual first, followed
  213. by the parts of the \*(PP Reference Manual necessary to build your application.
  214. In particular, you should read the section on \*(LP if you intend to build
  215. a client application around \*(PP, as this is not discussed at all in this
  216. manual.
  217. .\"---------------------------------------------------------------------------
  218. .sh 1 "The \*(PQ Query Language"
  219. .lp
  220. \*(PQ is the query language used for interacting with \*(PP.
  221. Here, we
  222. give an overview of how to use \*(PQ to access data.
  223. In other sections,
  224. user extensions to \*(PQ will be discussed.
  225. .\"------------------------------------
  226. .sh 2 "Creating a database"
  227. .lp
  228. Once \*(PP has been installed at your site by following
  229. the directions in the release notes, you can create a database named
  230. .cW foo
  231. using the following command:
  232. .(C
  233. % createdb foo
  234. .)C
  235. \*(PP allows you to create any number of databases at a
  236. given site and you automatically become the database
  237. administrator of the database just created.
  238. Database names must
  239. have an alphabetic first character and are limited to 16
  240. characters in length.
  241. .lp
  242. Once you have constructed a database, there are four ways to
  243. interact with it:
  244. .ip \(bu
  245. You can run the \*(PP terminal
  246. monitor which allows you to interactively enter, edit, and
  247. execute commands in the query language \*(PQ.
  248. .ip \(bu
  249. You can
  250. interact with \*(PP from a C program by using the \*(LP
  251. library of subroutine and call facilities.
  252. This allows you to submit
  253. \*(PQ commands from C and get answers and status messages back
  254. to your program.
  255. This interface is discussed further in the
  256. \*(LP section of the Reference Manual.
  257. .ip \(bu
  258. You can
  259. use the
  260. .b "fast path"
  261. facility,
  262. which
  263. allows you to directly execute functions stored in the database.
  264. This facility is described in the Reference Manual under
  265. .q "Fast Path."
  266. .ip \(bu
  267. \*(PP is accessible from the \*(OF programming
  268. environment.
  269. \*(OF is a graphical user interface (GUI) toolkit
  270. that allows a user to build sophisticated DBMS-oriented
  271. applications.
  272. \*(OF is a separate research project described
  273. in a collection of reports
  274. [WANG88, SCHA90] and is not treated further in this manual.
  275. .lp
  276. The terminal monitor can be activated for
  277. the
  278. .cW foo
  279. database by
  280. typing the command\**:
  281. .(f
  282. \**You may first need to set the
  283. .cW POSTGRESHOME
  284. environment variable to the name of the \*(PP root directory at your site,
  285. if it is not the default
  286. .cW /usr/postgres .
  287. If the \*(PP you wish to access is on a remote host, then you will also need to
  288. set the
  289. .cW PGHOST
  290. environment variable to the name of the remote host.
  291. .)f
  292. .(C
  293. % monitor foo
  294. .)C
  295. (the
  296. .cW % '' ``
  297. is your \*(UU shell prompt.)
  298. You will be greeted by the following message:
  299. .(C
  300. Welcome to the C POSTGRES terminal monitor
  301.  
  302. Go
  303. *
  304. .)C
  305. The
  306. .cW Go
  307. indicates the terminal monitor is listening to you and
  308. that you can type \*(PQ commands into a workspace maintained
  309. by the monitor.
  310. The monitor indicates it is listening by typing
  311. .cW *
  312. as a prompt.
  313. Printing the workspace can be performed by
  314. typing:
  315. .(C
  316. * \\p
  317. .)C
  318. and it can be passed to \*(PP for execution by typing:
  319. .(C
  320. * \\g
  321. .)C
  322. If you make a typing mistake, you can invoke the
  323. .cW vi
  324. text editor
  325. by typing:
  326. .(C
  327. * \\e
  328. .)C
  329. The workspace will be passed to the editor, and you have the full
  330. power of
  331. .cW vi
  332. to make any necessary changes.
  333. For more info on using
  334. .cW vi ,
  335. type
  336. .(C
  337. % man vi
  338. .)C
  339. Once you exit
  340. .cW vi ,
  341. your edited query will be in the monitor's query
  342. buffer and you can submit it to \*(PP by using the
  343. .cW \eg
  344. command
  345. described above.
  346. .lp
  347. To get out of the monitor and return to \*(UU, type
  348. .(C
  349. * \\q
  350. .)C
  351. and the monitor will respond:
  352. .(C
  353. I live to serve you.
  354. %
  355. .)C
  356. For a complete collection of monitor commands, see the manual page
  357. on
  358. .cW monitor
  359. in the \*(UU section of the Reference Manual.
  360. .lp
  361. If you are the database administrator for the database
  362. .cW foo ,
  363. you
  364. can destroy it using the following \*(UU command:
  365. .(C
  366. % destroydb foo
  367. .)C
  368. Other DBA commands include
  369. .cW createuser
  370. and
  371. .cW destroyuser ,
  372. which are discussed further in the \*(UU section of the Reference Manual.
  373. .\"------------------------------------
  374. .sh 2 "Classes and the Query Language \*(PQ"
  375. .\"-----------------
  376. .sh 3 "Basic Capabilities"
  377. .lp
  378. The fundamental notion in \*(PP is that of a
  379. .b class,
  380. which is a named collection of instances of objects.
  381. Each
  382. instance has the same collection of named attributes, and each
  383. attribute is of a specific type.
  384. Furthermore, each instance has
  385. an installation-wide unique (never-changing)
  386. .b "object identifier"
  387. or
  388. .b oid .
  389. .\"-----------------
  390. .sh 3 "Creating a New Class"
  391. .lp
  392. (In order to try out the following \*(PQ examples, create the
  393. .cW foo
  394. database
  395. as described in the previous section, and start the terminal
  396. monitor.)
  397. .lp
  398. A user can create a new class by specifying the class name,
  399. along with all attribute names and their types:
  400. .(C
  401. * create EMP (name = text, salary = int4,
  402.               age = int4, dept = char16) \\g
  403.  
  404. * create DEPT (dname = char16, floor = int4,
  405.                manager = text) \\g
  406. .)C
  407. The \*(PQ base types used above are
  408. a variable-length array of printable characters
  409. .cW text ), (
  410. a 4-byte signed integer
  411. .cW int4 ), (
  412. and a fixed-length array of 16 characters
  413. .cW char16 .)\** (
  414. .(f
  415. \**See
  416. .q "Built-In Types"
  417. in the Reference Manual.
  418. .)f
  419. Spaces, tabs and newlines may be used freely in \*(PQ queries.
  420. .lp
  421. So far, the
  422. .cW create
  423. command looks exactly like the create
  424. statement in a traditional relational system.
  425. However, we will presently see
  426. that classes have properties that are extensions of the
  427. relational model, so we use a different word to describe them.
  428. .\"-----------------
  429. .sh 3 "Populating a Class with Instances"
  430. .ds xX \n($1.\n($2.\n($3
  431. .lp
  432. To populate a class with instances, one can use the
  433. .cW append
  434. command:
  435. .(C
  436. * append EMP (name = "Joe", salary = 1400,
  437.               age = 40, dept = "shoe") \\g
  438.  
  439. * append EMP (name = "Sam", salary = 1200,
  440.               age = 29, dept = "toy") \\g
  441.  
  442. * append EMP (name = "Bill", salary = 1600,
  443.               age = 36, dept = "candy") \\g
  444. .)C
  445. This will add 3 instances to
  446. .cW EMP ,
  447. one for each
  448. .cW append
  449. command.
  450. .\"-----------------
  451. .sh 3 "Querying a Class"
  452. .lp
  453. The
  454. .cW EMP
  455. class can be queried with normal selection and
  456. projection queries.
  457. For example, to find the employees under 35 years of age,
  458. one would type:
  459. .(C
  460. * retrieve (EMP.name) where EMP.age < 35 \\g
  461. .)C
  462. and the output would be:
  463. .(T
  464. .TS
  465. allbox;
  466. l.
  467. name
  468. Sam
  469. .TE
  470. .)T
  471. Notice that parentheses are required around
  472. the
  473. .b "target list"
  474. of returned attributes
  475. (e.g.,
  476. .cW EMP.name .)
  477. .lp
  478. \*(PQ allows you to return
  479. computations in the target list as long as they are given a name
  480. (e.g.,
  481. .cW result ):
  482. .(C
  483. * retrieve (result = EMP.salary / EMP.age)
  484.       where EMP.name = "Bill" \\g
  485. .)C
  486. .\"-----------------
  487. .sh 3 "Redirecting retrieve queries"
  488. .lp
  489. Any retrieve query can be redirected to a
  490. new class in the database, and arbitrary boolean operators
  491. .cW and , (
  492. .cW or ,
  493. .cW not )
  494. are allowed in the qualification of any query:
  495. .(C
  496. * retrieve into temp (EMP.name)
  497.       where EMP.age < 35 and EMP.salary > 1000 \\g
  498. .)C
  499. .\"-----------------
  500. .sh 3 "Joins"
  501. .lp
  502. To find the names of employees which are the same age, one
  503. could write:
  504. .(C
  505. * retrieve (E1.name, E2.name)
  506.       from E1 in EMP, E2 in EMP
  507.       where E1.age = E2.age and E1.name != E2.name \\g
  508. .)C
  509. In this case both E1 and E2 are
  510. .b surrogates
  511. for an instance of the
  512. class
  513. .cW EMP ,
  514. and both range over all instances of the class.
  515. A \*(PQ
  516. query can contain an arbitrary number of class names and
  517. surrogates.\**
  518. .(f
  519. \**The semantics of such a join are that
  520. the qualification is a truth expression defined
  521. for the Cartesian product of the classes indicated in the query.
  522. For those instances in the Cartesian product for which the
  523. qualification is true, \*(PP must compute and return the
  524. target list.
  525. .)f
  526. .\"-----------------
  527. .sh 3 "Updates"
  528. .lp
  529. Updates are accomplished in \*(PQ using the
  530. .cW replace
  531. command:
  532. .(C
  533. * replace EMP (salary = E.salary)
  534.       from E in EMP
  535.       where EMP.name = "Joe" and E.name = "Sam" \\g
  536. .)C
  537. This command replaces the salary of Joe by that of Sam.
  538. .\"-----------------
  539. .sh 3 "Deletions"
  540. .lp
  541. Deletions are done using the
  542. .cW delete
  543. command:
  544. .(C
  545. * delete EMP where EMP.salary > 0 \\g
  546. .)C
  547. Since all employees have positive salaries, this command will
  548. leave the
  549. .cW EMP
  550. class empty.
  551. .\"-----------------
  552. .sh 3 "Arrays"
  553. .lp
  554. \*(PP supports both fixed-length and variable-length
  555. one-dimensional arrays.
  556. To illustrate their use, we first create a class with an array type.
  557. .(C
  558. * create SAL_EMP (name = char[],
  559.                   pay_by_quarter = int4[4]) \\g
  560. .)C
  561. The above query will create a class named
  562. .cW SAL_EMP
  563. with a variable-length array of
  564. .cW text
  565. strings
  566. .cW name ), (
  567. and an array of 4
  568. .cW int4
  569. integers
  570. .cW pay_by_quarter ), (
  571. which represents the employee's salary by quarter.
  572. Now we do some
  573. .cW append s;
  574. note that when appending to a non-character array, we enclose the values
  575. within braces and separate them by commas.
  576. .(C
  577. * append SAL_EMP (name = "bill",
  578.       pay_by_quarter = "{10000, 10000, 10000, 10000}") \\g
  579.  
  580. * append SAL_EMP (name = "jack",
  581.       pay_by_quarter = "{10000, 15000, 15000, 15000}") \\g
  582.  
  583. * append SAL_EMP (name = "joe",
  584.       pay_by_quarter = "{20000, 25000, 25000, 25000}") \\g
  585. .)C
  586. \*(PP uses the FORTRAN numbering convention for arrays\(emthat is, \*(PP
  587. arrays start with array[1] and end with array[n].
  588. .lp
  589. Now, we can run some
  590. queries on
  591. .cW SAL_EMP .
  592. This query retrieves the names of the employees whose pay changed in the
  593. second quarter:
  594. .(C
  595. * retrieve (SAL_EMP.name)
  596.       where SAL_EMP.pay_by_quarter[1] !=
  597.             SAL_EMP.pay_by_quarter[2] \\g
  598. .)C
  599. This query retrieves the third quarter pay of all employees:
  600. .(C
  601. * retrieve (SAL_EMP.pay_by_quarter[3]) \\g
  602. .)C
  603. This query deletes everyone from
  604. .cW SAL_EMP
  605. whose name begins with the letter
  606. .q j.
  607. .cW SAL_EMP
  608. should now contain only the employee named
  609. .q bill :
  610. .(C
  611. * delete SAL_EMP where SAL_EMP.name[1] = 'j' \\g
  612. .)C
  613. Let's make sure (note that the attribute
  614. .cW all
  615. may be used as a shorthand for all attributes of a class):
  616. .(C
  617. * retrieve (SAL_EMP.all) \\g
  618. .TS
  619. allbox tab(|);
  620. l l.
  621. name|pay_by_quarter
  622. bill|{10000,10000,10000,10000}
  623. .TE
  624. .)C
  625. \*(PP supports arrays of base and user-defined types, as well as
  626. .q "arrays of arrays,"
  627. as in the following example:
  628. .(C
  629. * create manager (name = char16, employees = text[]) \\g
  630.  
  631. * append manager (name = "mike",
  632.                   employees = "{"wei", "greg", "jeff"}") \\g
  633.  
  634. * append manager (name = "alice",
  635.                   employees = "{"bill", "joe"}") \\g
  636.  
  637. * append manager (name = "marge",
  638.                   employees = "{"mike", "alice"}") \\g
  639. .)C
  640. This creates a class
  641. .cW manager ,
  642. and provides a list of employees.
  643. .\"------------------------------------
  644. .sh 2 "Advanced \*(PQ"
  645. .lp
  646. Now we have covered the basics of using \*(PQ to access your data.
  647. In this section we will discuss those features of \*(PP which
  648. distinguish it from other data managers, such as
  649. inheritance
  650. and
  651. time travel.
  652. In the next section we will cover how the user can extend
  653. the query language via
  654. query language functions
  655. and
  656. composite objects,
  657. as well
  658. as additional extensions to \*(PP using
  659. user defined types,
  660. operators,
  661. and
  662. programming language functions.
  663. .\"-----------------
  664. .sh 3 "Inheritance"
  665. .lp
  666. First, re-populate the
  667. .cW EMP
  668. class by repeating the
  669. .cW append
  670. commands in section \*(xX.
  671. Then, create a second class
  672. .cW STUD_EMP ,
  673. and populate it as follows:
  674. .(C
  675. * create STUD_EMP (location = point) inherits (EMP) \\g
  676.  
  677. * append STUD_EMP (name = "Sunita", salary = 1300,
  678.                    age = 41, dept = "electronics",
  679.                    location = "(3, 5)") \\g
  680. .)C
  681. In this case, an instance of
  682. .cW STUD_EMP
  683. .b inherits
  684. all data fields
  685. .cW name , (
  686. .cW salary ,
  687. .cW age ,
  688. and
  689. .cW dept )
  690. from its parent,
  691. .cW EMP .
  692. Furthermore, student employees have an extra field,
  693. .cW location ,
  694. that shows their address as a coordinate pair.
  695. In
  696. \*(PP, a class can inherit from zero or more other classes,\**
  697. .(f
  698. \**i.e.,
  699. the inheritance hierarchy is a directed acyclic graph.
  700. .)f
  701. and a query can reference either all
  702. instances of a class or all instances of a class plus all of its
  703. descendants.
  704. For example, the following query finds the
  705. employees over 39:
  706. .(C
  707. * retrieve (E.name) from E in EMP where E.age > 39 \\g
  708. .)C
  709. On the other hand, to find the names of all
  710. employees, including student employees, over age 40, the query is:
  711. .(C
  712. * retrieve (E.name) from E in EMP* where E.age > 39 \\g
  713. .)C
  714. which returns:
  715. .(T
  716. .TS
  717. allbox;
  718. l.
  719. name
  720. Joe
  721. Sunita
  722. .TE
  723. .)T
  724. Here the
  725. .cW *
  726. after
  727. .cW EMP
  728. indicates that the query should be run over
  729. .cW EMP
  730. and all classes below
  731. .cW EMP
  732. in the inheritance hierarchy.
  733. .lp
  734. Note that
  735. .cW location
  736. in
  737. .cW STUD_EMP
  738. is not a traditional
  739. relational data type.
  740. As we will see later, \*(PP can be
  741. customized with an arbitrary number of user-defined data types.
  742. .\"-----------------
  743. .sh 3 "Time Travel"
  744. .lp
  745. \*(PP supports the notion of
  746. .b "time travel" .
  747. This
  748. feature allows a user to run historical queries.
  749. For example, to
  750. find Sam's current salary, one would query:
  751. .(C
  752. * retrieve (E.salary) from E in EMP["now"]
  753.       where E.name = "Sam" \\g
  754. .)C
  755. \*(PP will automatically find the version of Sam's record
  756. valid at the correct time and get the appropriate salary.
  757. .lp
  758. One can also
  759. give a time
  760. .b range .
  761. For example to see all the salaries that Sam has
  762. ever earned, one would query:
  763. .(C
  764. * retrieve (E.salary)
  765.       from E in EMP["Jan 1 00:00:00 1970 GMT", "now"]
  766.       where E.name = "Sam" \\g
  767. .)C
  768. If you have executed all of the examples so far, then the above query returns:
  769. .(T
  770. .TS
  771. allbox;
  772. l.
  773. salary
  774. 1200
  775. 1200
  776. .TE
  777. .)T
  778. There are two salaries for Sam, since he was deleted from and then
  779. re-appended to the
  780. .cW EMP
  781. class.
  782. .lp
  783. The default beginning of a time range is the origin of the system clock
  784. (which just happens to be
  785. .cW "Jan 1 00:00:00 1970 GMT" '' ``
  786. on \*(UU systems),
  787. and the default end is the current time;
  788. thus, the above time range can be abbreviated as
  789. .cW [,] .'' ``
  790. .\"---------------------------------------------------------------------------
  791. .sh 1 "User Extensions to \*(PQ"
  792. .lp
  793. Here, we will discuss user extensions to the \*(PQ query language,
  794. query language functions, composite types, and user defined types, functions
  795. and operators.
  796. .\"------------------------------------
  797. .sh 2 "User Defined \*(PQ Functions"
  798. .lp
  799. \*(PQ provides two types of functions:
  800. .b "query language functions"
  801. (functions written in \*(PQ)
  802. and
  803. .b "programming language functions"
  804. (functions written in a separately-compiled programming language such as C.)
  805. In this section we will cover \*(PQ functions; programming language
  806. functions will be covered below with the discussion on user-defined types.
  807. .lp
  808. Any collection of commands in the \*(PQ
  809. query language can be packaged together and defined as a
  810. function, usually returning either a set of instances or a set of base types.
  811. For example, the following function
  812. .cW high_pay
  813. returns all employees in class
  814. .cW EMP
  815. whose salaries exceed 50,000:
  816. .(C
  817. * define function high_pay
  818.       (language = "postquel", returntype = setof EMP)
  819.       as retrieve (EMP.all) where EMP.salary > 50000 \\g
  820. .)C
  821. \*(PQ functions can also have parameters.
  822. The following function
  823. .cW large_pay
  824. allows the threshold salary to be specified as an argument:
  825. .(C
  826. * define function large_pay
  827.       (language = "postquel", returntype = setof EMP)
  828.       arg is (int4)
  829.       as retrieve (EMP.all) where EMP.salary > $1 \\g
  830. .)C
  831. In addition to their obvious utility as
  832. .q aliases
  833. for commonly-used queries,
  834. \*(PQ functions are useful for creating composite types, as described
  835. below.
  836. .\"------------------------------------
  837. .sh 2 "Composite Types"
  838. .lp
  839. Since \*(PQ functions return instances or sets of instances,
  840. they are the mechanism used to assign values to composite
  841. types.
  842. For example, consider extending the
  843. .cW EMP
  844. class with a
  845. .cW manager
  846. field.
  847. That is, for each instance of
  848. .cW EMP ,
  849. we want to associate another
  850. instance of
  851. .cW EMP 
  852. corresponding to the manager of the first instance.
  853. Specifically, we will
  854. define a \*(PQ function
  855. .cW manager :
  856. .(C
  857. * define function manager
  858.       (language = "postquel", returntype = EMP)
  859.       arg is (EMP)
  860.       as "retrieve (E.all) from E in EMP
  861.               where E.name = DEPT.manager
  862.               and DEPT.name = $1.dept" \\g
  863. .)C
  864. The function
  865. .cW manager
  866. takes an instance as its only argument, so \*(PQ allows referencing
  867. into it with the use of the nested dot notation.
  868. Whenever such a
  869. function is defined over a class, a user can utilize the cascaded dot
  870. notation to reference into (i.e. access the fields of) the objects
  871. returned by the function.
  872. .lp
  873. The following query finds all the employees who work for
  874. Joe:
  875. .(C
  876. * retrieve (EMP.name) where EMP.manager.name = "Joe" \\g
  877. .)C
  878. This is exactly equivalent to:
  879. .(C
  880. * retrieve (EMP.name)
  881.       where name(manager(EMP)) = "Joe" \\g
  882. .)C
  883. Here, we have essentially added an attribute to the
  884. .cW EMP
  885. class which is of
  886. type
  887. .cW EMP ,
  888. i.e. it has a value which is an instance of
  889. the class
  890. .cW EMP .
  891. Since the value of
  892. .cW manager
  893. has a record-oriented structure, we call it a
  894. .b "composite object" .
  895. Consequently, the user can think of the function
  896. .cW manager
  897. as an attribute of
  898. .cW EMP
  899. and can reference it just like any other
  900. attribute, with the following two exceptions.
  901. First, one cannot do
  902. direct
  903. .cW append s\(emthat
  904. is,
  905. .(C
  906. * append emp (emp.manager.name = "Smith") \\g
  907. .)C
  908. .b won't
  909. work.
  910. Non-projected
  911. retrieves will also be rejected,
  912. i.e.:
  913. .(C
  914. * retrieve (emp.manager) \\g
  915. .)C
  916. will result
  917. in a warning from the \*(PQ language parser.
  918. .lp
  919. Note that 
  920. .cW manager
  921. is defined as returning a single instance of
  922. .cW EMP.
  923. We can also write a \*(PQ function that returns sets of
  924. instances.
  925. For example, consider the function
  926. .(C
  927. * define function children
  928.       (language = "postquel", returntype = setof KIDS)
  929.       arg is (EMP)
  930.       as "retrieve (KIDS.all)
  931.               where $1.name = KIDS.dad
  932.               or $1.name = KIDS.mom"\\g
  933. .)C
  934. The
  935. .cW children
  936. function is defined as returning a set of instances, rather than a
  937. single instance.
  938. Given the query
  939. .(C
  940. * retrieve(emp.name, emp.children.name)
  941. .)C
  942. if the query in the body of the
  943. .cW children
  944. function returns many instances, the retrieve query will return all of
  945. them, in a
  946. .q flattened
  947. form.
  948. If the query in the body of
  949. .cW manager
  950. returns more than one instance,
  951. the
  952. .cW manager
  953. function will return only one instance, arbitrarily chosen from the
  954. set returned by the query in the function's body.
  955. See the \*(PP
  956. Reference Manual's entry on the 
  957. .cW "define function"
  958. command for further details and examples.
  959.  
  960. .\"---------------------------------------------------------------------------
  961. .sh 1 "User Defined Types, Operators, and Programming Language Functions"
  962. .lp
  963. The central concept of extending \*(PP lies in \*(PP's ability to
  964. .b "dynamically load"
  965. a binary object file created by the user.
  966. This allows \*(PP to call
  967. arbitrary user functions which can be written in a standard programming
  968. language.
  969. These functions can then be used:
  970. .ip \(bu
  971. to convert between
  972. .b internal
  973. (binary) and
  974. .b external
  975. (character string) representations of
  976. user-defined
  977. types;
  978. .ip \(bu
  979. as operators; and
  980. .ip \(bu
  981. to
  982. define ordering for indices on user-defined types.
  983. .lp
  984. \*(PP's concept of types includes
  985. .b built-in
  986. types and
  987. .b user-defined
  988. types.
  989. Built-in types are those required by the system to bootstrap itself.
  990. User-defined types are those created by the user in the manner described
  991. below.
  992. There is no intrinsic performance difference between using a system
  993. type or user-defined type, other than the overhead due to the complexity of
  994. the type itself.
  995. .\"------------------------------------
  996. .sh 2 "Internal storage of types"
  997. .lp
  998. Internally,
  999. \*(PP regards a user-defined type as a
  1000. .q "blob of memory"
  1001. upon which
  1002. user-defined functions impose structure and meaning.
  1003. \*(PP will store and retrieve the data from disk and use user-defined
  1004. functions to input, process, and output the data.
  1005. .\"------------------------------------
  1006. .sh 2 "Functions needed for a user-defined type"
  1007. .lp
  1008. A completely defined user type requires the following user-defined functions:
  1009. .ip \(bu
  1010. .b input
  1011. and
  1012. .b output
  1013. functions for the type:
  1014. These functions determine how the type appears in strings
  1015. (for input by the user and output to the user) and how the type is organized
  1016. in memory.
  1017. These at least are necessary to define the type.
  1018. .ip \(bu
  1019. .b operator
  1020. functions for the type:
  1021. These functions define the meanings of
  1022. .q equal,
  1023. .q "less than,"
  1024. .q "greater than,"
  1025. etc., for your type.
  1026. .\"------------------------------------
  1027. .sh 2 "An Example User Defined Type"
  1028. .lp
  1029. In this discussion, we will be defining a
  1030. .cW circle
  1031. type, using functions written in the C programming language.
  1032. .\"-----------------
  1033. .sh 3 "Data structures for our type"
  1034. .lp
  1035. Before we do anything, we have to decide on what a circle looks
  1036. like, both in string format and internally in memory.
  1037. Circles
  1038. have a center and a radius, so a reasonable string representation of a circle
  1039. would be an ordered triple:
  1040. .(l
  1041. (center_x, center_y, radius)
  1042. .)l
  1043. where each element is a real number with arbitrary units,
  1044. e.g.:
  1045. .(C
  1046. (5.0, 10.3, 3)
  1047. .)C
  1048. This is what
  1049. the input to the circle input function looks like,
  1050. and what the output from the circle output function looks
  1051. like.
  1052. .lp
  1053. Now we have to come up with an internal representation for
  1054. a circle in memory.
  1055. The following
  1056. declarations are legal
  1057. and reasonable given the format we chose above:
  1058. .(C
  1059. typedef struct {
  1060.     double x, y;
  1061. } POINT;
  1062.  
  1063. typedef struct {
  1064.     POINT center;
  1065.     double r;
  1066. } CIRCLE;
  1067. .)C
  1068. Memory containing values of type
  1069. .cW CIRCLE
  1070. will be written to
  1071. disk and read from disk, so
  1072. .cW CIRCLE
  1073. must be both
  1074. .b complete
  1075. and
  1076. .b contiguous ;
  1077. that is, it cannot contain any pointers.
  1078. The alternate declaration
  1079. .(C
  1080. typedef struct {
  1081.     POINT *center
  1082.     double r;
  1083. } CIRCLE;
  1084. .)C
  1085. will
  1086. .b NOT
  1087. work,
  1088. because only the address stored in
  1089. .cW center
  1090. would be written to disk, not the
  1091. .cW POINT
  1092. structure that
  1093. .cW center
  1094. presumably points to.
  1095. \*(PP cannot detect this kind of coding error;
  1096. you must guard against it yourself.
  1097. .\"-----------------
  1098. .sh 3 "Defining the input and output functions for our type"
  1099. .lp
  1100. Suppose in defining our type
  1101. .q circle,
  1102. we have a C source file called
  1103. .cW circle.c ,
  1104. and a corresponding object code file
  1105. .cW /usr/postgres/tutorial/circle.o .
  1106. (All functions related to our
  1107. .cW circle
  1108. type have to be in the same
  1109. object file.)
  1110. For the sake of argument, suppose we our platform is a DECstation,
  1111. where sizeof(double) is 8 bytes (this will be important later).
  1112. .lp
  1113. We will create source file
  1114. .cW circle.c ,
  1115. containing C source code for the functions that support our
  1116. .cW CIRCLE
  1117. type.
  1118. .cW circle.c
  1119. contains
  1120. three functions:
  1121. .ip \(bu
  1122. .cW circle_in ,
  1123. which is the input function for circles.
  1124. It
  1125. takes a string as an argument and returns a pointer to a
  1126. .cW CIRCLE .
  1127. .ip \(bu
  1128. .cW circle_out ,
  1129. which is the output function for circles.
  1130. It is
  1131. takes a pointer to s
  1132. .cW CIRCLE
  1133. as input and returns a string.
  1134. .ip
  1135. The return value of
  1136. .cW circle_in
  1137. must be a legal argument to
  1138. .cW circle_out ,
  1139. and vice versa.
  1140. .ip \(bu
  1141. .cW eq_area_circle ,
  1142. which is the equality function for
  1143. circles.
  1144. For the purposes of this discussion, circles are equal
  1145. if their areas are equal.
  1146. .lp
  1147. The contents of
  1148. .cW circle.c
  1149. are:
  1150. .(C
  1151. #include <math.h>
  1152. #include <stdio.h>
  1153. #include <string.h>
  1154.  
  1155. #include "tmp/c.h"           /* (always)                 */
  1156. #include "utils/geo-decls.h" /* for POINT declaration    */
  1157. #include "utils/palloc.h"    /* for palloc() declaration */
  1158.  
  1159. typedef struct {
  1160.     POINT  center;
  1161.     double radius;
  1162. } CIRCLE;
  1163.  
  1164. #define LDELIM '('
  1165. #define RDELIM ')'
  1166. #define NARGS  3
  1167.  
  1168. CIRCLE *
  1169. circle_in(str)
  1170.     char   *str;
  1171. {
  1172.     char   *p, *coord[NARGS];
  1173.     int    i;
  1174.     CIRCLE *result;
  1175.  
  1176.     if (str == NULL) return(NULL);
  1177.  
  1178.     for (i = 0, p = str;
  1179.          *p && i < NARGS && *p != RDELIM;
  1180.          p++)
  1181.     {
  1182.         if (*p == ',' || (*p == LDELIM && !i))
  1183.             coord[i++] = p + 1;
  1184.     }
  1185.  
  1186.     if (i < NARGS - 1) return(NULL);
  1187.  
  1188.     result = (CIRCLE *) palloc(sizeof(CIRCLE));
  1189.  
  1190.     result->center.x = atof(coord[0]);
  1191.     result->center.y = atof(coord[1]);
  1192.     result->radius = atof(coord[2]);
  1193.  
  1194.     return(result);
  1195. }
  1196.  
  1197. char *
  1198. circle_out(circle)
  1199.     CIRCLE *circle;
  1200. {
  1201.     char   *result;
  1202.  
  1203.     if (circle == NULL) return(NULL);
  1204.  
  1205.     result = (char *) palloc(60);
  1206.  
  1207.     sprintf(result, "(%g, %g, %g)",
  1208.             circle->center.x, circle->center.y,
  1209.             circle->radius);
  1210.  
  1211.     return(result);
  1212. }
  1213.  
  1214. int
  1215. eq_area_circle(circle1, circle2)
  1216.     CIRCLE *circle1, *circle2;
  1217. {
  1218.     return(circle1->radius == circle2->radius);
  1219. }
  1220. .)C
  1221. .lp
  1222. Now that we have written these functions and compiled the source file,\**
  1223. .(f
  1224. \**You will need to supply an option like
  1225. .cW -I$POSTGRESHOME/src/lib/H
  1226. to your C compiler so it can find the \*(PP
  1227. .cW .h '' ``
  1228. files.
  1229. Also, various platform-specific compiler options may be required to support
  1230. \*(PP dynamic linking (for example, the DECstation ULTRIX compiler requires
  1231. the
  1232. .cW "-G0" '' ``
  1233. option.)
  1234. See
  1235. .q "define function"
  1236. in the Reference Manual for details.
  1237. .)f
  1238. we have to let \*(PP know that they exist.
  1239. First, we
  1240. run the following queries to define the input and
  1241. output functions.
  1242. These functions must be defined
  1243. .b before
  1244. we define the
  1245. type.
  1246. \*(PP will
  1247. notify you that return type circle is not defined yet, but this
  1248. is OK\**:
  1249. .(f
  1250. \**By default,
  1251. user-defined C functions use addresses instead of values for all but
  1252. .q small
  1253. (<= 4-byte) argument and return types,
  1254. so we can use the \*(PQ type
  1255. .cW char16
  1256. as a placeholder for the C type
  1257. .cW "char *" .
  1258. .)f
  1259. .(C
  1260. * define function circle_in
  1261.       (language = "c", returntype = circle)
  1262.       arg is (char16)
  1263.       as "/usr/postgres/tutorial/circle.o" \\g
  1264.  
  1265. * define function circle_out
  1266.       (language = "c", returntype = char16)
  1267.       arg is (circle)
  1268.       as "/usr/postgres/tutorial/circle.o" \\g
  1269. .)C
  1270. Note that the full pathname of the object code file must be specified,
  1271. so you would change
  1272. .cW /usr/postgres/tutorial
  1273. to whatever is appropriate for your installation.
  1274. .lp
  1275. Now we can define the
  1276. .cW circle
  1277. type:
  1278. .(C
  1279. * define type circle
  1280.       (internallength = 24,
  1281.        input = circle_in, output = circle_out) \\g
  1282. .)C
  1283. where
  1284. .cW internallength
  1285. is the size of the
  1286. .cW CIRCLE
  1287. structure
  1288. in bytes.
  1289. For circles, the type members are three
  1290. .cW double s,
  1291. which on most platforms are 8 bytes each, with no additional alignment
  1292. constraints.
  1293. However,
  1294. when defining your own types, you should
  1295. .b not
  1296. make assumptions about structure sizes,
  1297. but instead
  1298. write a test program
  1299. that does a
  1300. .(C
  1301. printf("size is %d\en", sizeof (MYTYPE));
  1302. .)C
  1303. on your type.
  1304. .lp
  1305. If
  1306. .cW internallength
  1307. is defined incorrectly, you will encounter strange errors which may crash
  1308. the data manager itself.
  1309. If this were to happen with our
  1310. .cW CIRCLE
  1311. type,
  1312. we would have to do a
  1313. .(C
  1314. * remove type circle \\g
  1315. .)C
  1316. and then redefine the
  1317. .cW circle
  1318. type correctly.
  1319. Note that we would
  1320. .b not
  1321. have to redefine our functions,
  1322. since their behavior would not have changed.
  1323. .\"-----------------
  1324. .sh 3 "Defining an operator for our type"
  1325. .lp
  1326. Now that we have finished defining the
  1327. .cW circle
  1328. type, we can
  1329. .cW create
  1330. classes with circles in them,
  1331. .cW append
  1332. records to them
  1333. with circles defined, and
  1334. .cW retrieve
  1335. the values of the entire list
  1336. of records.
  1337. But we can do nothing else until we have some circle
  1338. operators.
  1339. To do this, we make use of the concept of
  1340. .b "operator overloading" ,
  1341. and in this case we will set the \*(PP equality
  1342. operator
  1343. .cW = '' ``
  1344. to work for circles.
  1345. First we have to tell \*(PP
  1346. that our circle equality function exists:
  1347. .(C
  1348. * define function eq_area_circle
  1349.       (language = "c", returntype = bool)
  1350.       arg is (circle, circle)
  1351.       as "/usr/postgres/tutorial/circle.o" \\g
  1352. .)C
  1353. We will now bind this function to the
  1354. equality symbol with the following query:
  1355. .(C
  1356. * define operator =
  1357.       (arg1 = circle, arg2 = circle,
  1358.        procedure = eq_area_circle) \\g
  1359. .)C
  1360. .\"-----------------
  1361. .sh 3 "Using our type"
  1362. .lp
  1363. Let's create a class
  1364. .cW tutorial
  1365. that contains a
  1366. .cW circle
  1367. attribute,
  1368. and run some queries against it:
  1369. .(C
  1370. * create tutorial(a = circle) \\g
  1371.  
  1372. * append tutorial (a = "(1.0, 1.0, 10.0)"::circle) \\g
  1373.  
  1374. * append tutorial (a = "(2.0, 2.0, 5.0)"::circle) \\g
  1375.  
  1376. * append tutorial (a = "(0.0, 1.8, 10.0)"::circle) \\g
  1377.  
  1378. * retrieve (tutorial.all)
  1379.       where tutorial.a = "(0.0, 0.0, 10.0)"::circle \\g
  1380. .)C
  1381. which returns:
  1382. .(T
  1383. .TS
  1384. allbox;
  1385. l.
  1386. a
  1387. (1.0, 1.0, 10.0)
  1388. (0.0, 1.8, 10.0)
  1389. .TE
  1390. .)T
  1391. Recall that we defined circles as being equal if their areas were
  1392. equal.
  1393. .lp
  1394. Other operators (less than, greater than, etc.) can be defined in
  1395. a similar way.
  1396. Note that the
  1397. .cW = '' ``
  1398. symbol will still work for
  1399. other types\(emit has merely had a new type added to the list of
  1400. types it works on.
  1401. Any string of
  1402. .q "punctuation characters"
  1403. other than
  1404. brackets,
  1405. braces, or parentheses can be used in defining an operator.
  1406. .\"------------------------------------
  1407. .sh 2 "Additional info on creating a user-defined function"
  1408. .\"-----------------
  1409. .sh 3 "Use palloc and not malloc"
  1410. .lp
  1411. In order for \*(PP to correctly manage memory associated with processing your
  1412. type, you
  1413. must use the memory allocator
  1414. .cW palloc
  1415. and avoid standard \*(UU memory managers
  1416. such as
  1417. .cW malloc .
  1418. If you do not, \*(PP will chew up ever increasing amounts of
  1419. memory.
  1420. .cW palloc
  1421. has the same arguments as
  1422. .cW malloc ,
  1423. that is
  1424. .(C
  1425. char *palloc(size)
  1426. unsigned long size;
  1427. .)C
  1428. To free memory allocated with
  1429. .cW palloc ,
  1430. use
  1431. .cW pfree ,
  1432. which is analogous to
  1433. the \*(UU library function
  1434. .cW free :
  1435. .(C
  1436. void pfree(ptr)
  1437. char *ptr;
  1438. .)C
  1439. .\"-----------------
  1440. .sh 3 "Re-loading user functions"
  1441. .lp
  1442. In the process of creating a user-defined type, you may find it necessary to
  1443. re-load a function in the course of debugging.
  1444. This is
  1445. .b not
  1446. done automatically when you edit or re-compile the file, but
  1447. .b is
  1448. done if you quit and restart the data manager.
  1449. .lp
  1450. We would re-load our example functions by using the following command:
  1451. .(C
  1452. * load "/usr/postgres/tutorial/circle.o" \\g
  1453. .)C
  1454. .\"-----------------
  1455. .sh 3 "Writing a Function of an Instance"
  1456. .lp
  1457. We've already discussed user functions which take \*(PP base or user defined
  1458. types as arguments; in this section, we will discuss inheritable C functions
  1459. or methods.
  1460. .lp
  1461. C language methods are useful particularly when we want to make a function
  1462. .b inheritable ;
  1463. that is, to have the function process every instance in an inheritance
  1464. hierarchy of classes.
  1465. .lp
  1466. In using a function of an instance in qualifying an instance,
  1467. \*(PP defines the
  1468. .q "current instance"
  1469. to be the instance being qualified at the moment your function is
  1470. called.
  1471. The instance itself will be passed in your function's
  1472. parameter list as an opaque structure of type TUPLE, and you will use
  1473. \*(PP library routines to access the data in the object as described
  1474. below.\**
  1475. .(f
  1476. \**In \*(PP \*(PV,
  1477. .cW TUPLE
  1478. is defined as
  1479. .cW "void *" .
  1480. .)f
  1481. .cW 
  1482. .lp
  1483. Suppose we want to write a function to answer the query
  1484. .(C
  1485. * retrieve (EMP.all) where overpaid(EMP) \\g
  1486. .)C
  1487. In the query above, a reasonable
  1488. .cW overpaid
  1489. function might be:
  1490. .(C
  1491. bool
  1492. overpaid(t) 
  1493. TUPLE t;   /* the current instance */
  1494. {
  1495.     extern char *GetAttributeByName();
  1496.     short salary, seniority, performance;
  1497.  
  1498.     salary = (short) GetAttributeByName(t, "salary");
  1499.     seniority = (short) GetAttributeByName(t, "seniority");
  1500.     performance = (short) GetAttributeByName(t, "performance");
  1501.  
  1502.     return (salary > (seniority * performance));
  1503. }
  1504. .)C
  1505. .cW GetAttributeByName
  1506. is the \*(PP system function that returns
  1507. attributes out of the current instance.
  1508. It has two arguments: the argument of type TUPLE passed into the function,
  1509. and the name of the desired attribute.
  1510. .cW GetAttributeByName
  1511. will align data properly so you can cast its return value to
  1512. the desired type.
  1513. For example, if you have an attribute
  1514. .cW name
  1515. which is of the \*(PQ type
  1516. .cW char16 ,
  1517. the
  1518. .cW GetAttributeByName
  1519. call would look like:
  1520. .(C
  1521. char *str;
  1522. \&...
  1523. str = (char *) GetAttributeByName(t, "name")
  1524. .)C
  1525. .lp
  1526. To let \*(PP know about the
  1527. .cW overpaid
  1528. function,
  1529. do:
  1530. .(C
  1531. * define function overpaid
  1532.       (language = "c", returntype = bool)
  1533.       arg is (EMP)
  1534.       as "/usr/postgres/tutorial/overpaid.o" \\g
  1535. .)C
  1536. .lp
  1537. You can have additional complex, base or user-defined types as
  1538. arguments to the inheritable function.
  1539. Thus,
  1540. .(C
  1541. * retrieve (EMP.all)
  1542.       where overpaid2(EMP, DEPT, "bill", 8) \\g
  1543. .)C
  1544. could be written, and
  1545. .cW overpaid2
  1546. would be declared:
  1547. .(C
  1548. bool
  1549. overpaid2(emp, dept, name, number)
  1550.     TUPLE emp, dept;
  1551.     char *name;
  1552.     long number;
  1553. .)C
  1554. .\"------------------------------------
  1555. .sh 2 "Arrays of types"
  1556. .lp
  1557. As discussed above, \*(PP fully supports arrays of base types.
  1558. Additionally,
  1559. \*(PP supports arrays of user-defined types as well.
  1560. When you define a type,
  1561. \*(PP
  1562. .b automatically
  1563. provides support for arrays of that type.
  1564. .\"-----------------
  1565. .sh 3 "Arrays of user-defined types"
  1566. .lp
  1567. Using the
  1568. .q circle
  1569. example discussed above, we will create a class containing
  1570. an array of
  1571. circles:
  1572. .(C
  1573. * create circles (list = circle[]) \\g
  1574. .)C
  1575. and do some appends
  1576. .(C
  1577. * append circles (list = "{"(1.0, 1.0, 5.0)",
  1578.                          "(2.0, 2.0, 10.0)"}") \\g
  1579.  
  1580. * append circles (list = "{"(2.0, 3.0, 15.0)",
  1581.                          "(2.0, 2.0, 10.0)"}") \\g
  1582.  
  1583. * append circles (list = "{"(2.0, 3.0, 4.0)"}") \\g
  1584. .)C
  1585. We can now run queries like:
  1586. .(C
  1587. * retrieve (circles.list[1]) \\g
  1588. .)C
  1589. which returns the first element of each
  1590. .cW list :
  1591. .(T
  1592. .TS
  1593. allbox;
  1594. l.
  1595. list
  1596. (1, 1, 5)
  1597. (2, 3, 4)
  1598. .TE
  1599. .)T
  1600. and
  1601. .(C
  1602. * retrieve (circles.all)
  1603.       where circles.list[1] = "(0.0, 0.0, 4.0)" \\g
  1604. .)C
  1605. which returns:
  1606. .(T
  1607. .TS
  1608. allbox;
  1609. l.
  1610. list
  1611. {"(2, 3, 4)"}
  1612. .TE
  1613. .)T
  1614. Note the
  1615. .cW {} s,
  1616. indicating that an array has been retrieved, as opposed to a single element.
  1617. .\"-----------------
  1618. .sh 3 "Defining a new array type"
  1619. .lp
  1620. An array may be defined as an element of a class, as shown above, or it may
  1621. be defined as a type in and of itself.
  1622. This is useful for defining
  1623. .b "arrays of arrays" .
  1624. .lp
  1625. The special built-in functions
  1626. .cW array_in
  1627. and
  1628. .cW array_out
  1629. are used by \*(PP to input and output arrays of any existing type.
  1630. Here,
  1631. we define an array of integers:
  1632. .(C
  1633. * define type int_array
  1634.       (element = int4, internallength = variable,
  1635.        input = array_in, output = array_out) \\g
  1636. .)C
  1637. The
  1638. .cW element
  1639. parameter indicates that this is an array, and setting
  1640. .cW internallength
  1641. to
  1642. .cW variable
  1643. indicates that the array is a variable-length attribute.\**
  1644. .(f
  1645. \**Note
  1646. that any type using
  1647. .cW array_in
  1648. and
  1649. .cW array_out
  1650. .b must
  1651. be variable-length.
  1652. .)f
  1653. .lp
  1654. We can use our type defined above to create an array of integer arrays:
  1655. .(C
  1656. * define type int_arrays
  1657.       (element = int_array, internallength = variable,
  1658.        input = array_in, output = array_out) \\g
  1659.  
  1660. * create stuff (a = int_arrays) \\g
  1661.  
  1662. * append stuff (a = "{{1, 2, 3} , {4, 5}, {6, 7, 8}}") \\g
  1663.  
  1664. * append stuff (a = "{{88, 99, 3}}") \\g
  1665.  
  1666. * append stuff (a = "{{5, 4, 3} , {2, 2}}") \\g
  1667.  
  1668. * retrieve (stuff.a[1])
  1669.       where stuff.a[1][1] < stuff.a[1][2] \\g
  1670.  
  1671. * retrieve (stuff.a)
  1672.       where stuff.a[3][1] < stuff.a[1][2] \\g
  1673.  
  1674. * retrieve (s.all) from s in stuff
  1675.       where s.a[2][2] = stuff.a[1][1] \\g
  1676. .)C
  1677. We can also define operators for equality, less than, greater than, etc. which
  1678. operate on our new array type as necessary.
  1679. .\"-----------------
  1680. .sh 3 "Creating an array type from scratch"
  1681. .lp
  1682. There are many situations in which the above scheme for creating an array
  1683. type is inappropriate, particularly when it is necessary to define a
  1684. fixed-length array.
  1685. In this section, we will create an array of four longs called
  1686. .cW quarterly ,
  1687. and a variable-length array of longs called
  1688. .cW  stats .\**
  1689. .(f
  1690. We assume
  1691. .cW sizeof(long)
  1692. == 4.
  1693. .)f
  1694. .lp
  1695. The only special things we need to know when writing the input and output
  1696. functions for
  1697. .cW quarterly
  1698. is that \*(PP will pass a
  1699. .q simple
  1700. (i.e. fixed-length) array of
  1701. .cW long s
  1702. to the
  1703. output function and expect a simple array of
  1704. .cW long s
  1705. in return from the input
  1706. function.
  1707. A simple array suitable for
  1708. .cW quarterly
  1709. can be declared:
  1710. .(C
  1711. long quarterly[4];
  1712. .)C
  1713. For the variable-length array
  1714. .cW stats ,
  1715. the situation is a little more
  1716. complicated.
  1717. Because \*(PP will not know in advance how big the array is,
  1718. \*(PP will expect the length of the array (in bytes) to be encoded in the
  1719. first four bytes of the memory which contains the array.
  1720. The expected
  1721. structure is:
  1722. .(C
  1723. typedef struct {
  1724.     long length;
  1725.     unsigned char bytes[1]; /* Force contiguity */
  1726. } VAR_LEN_ATTR;
  1727. .)C
  1728. The input function for the
  1729. .cW stats
  1730. array will look something like:
  1731. .(C
  1732. VAR_LEN_ATTR *
  1733. stats_in(s)
  1734.     char s;
  1735. {
  1736.     VAR_LEN_ATTR *stats;
  1737.     long array_size, *arrayp, nbytes;
  1738.  
  1739.     /*
  1740.      * nbytes is the total number of bytes in stats,
  1741.      * INCLUDING the byte count at the beginning
  1742.      */
  1743.     nbytes = array_size * sizeof(long)  +  sizeof(long);
  1744.  
  1745.     stats = (VAR_LEN_ATTR *) palloc(nbytes);
  1746.  
  1747.     stats->length = nbytes;
  1748.  
  1749.     arrayp = &(stats->bytes[0]);
  1750.  
  1751.     /*
  1752.      * put code here that loads interesting stuff into
  1753.      * arrayp[0] .. arrayp[array_size]
  1754.      */
  1755.  
  1756.     return(stats);
  1757. }
  1758. .)C
  1759. The output function for
  1760. .cW stats
  1761. will get the same
  1762. .cW VAR_LEN_ATTR
  1763. structure.
  1764. .lp
  1765. Now,
  1766. assuming the functions are in
  1767. .cW /usr/postgres/tutorial/stats.c
  1768. and
  1769. .cW /usr/postgres/tutorial/quarterly.c ,
  1770. we
  1771. can define our two arrays.
  1772. First we will define the fixed-size array
  1773. .cW quarterly .\**
  1774. .(f
  1775. .cW internallength
  1776. == 16 follows from our assumption about
  1777. .cW sizeof(long) .
  1778. .)f
  1779. .(C
  1780. * define function quarterly_in
  1781.       (language = "c", returntype = quarterly)
  1782.       arg is (char16)
  1783.       as "/usr/postgres/tutorial/quarterly.o" \\g
  1784.  
  1785. * define function quarterly_out
  1786.       (language = "c", returntype = char16)
  1787.       arg is (quarterly)
  1788.       as "/usr/postgres/tutorial/quarterly.o" \\g
  1789.  
  1790. * define type quarterly
  1791.       (element = int4, internallength = 16,
  1792.        input = quarterly_in, output = quarterly_out) \\g
  1793. .)C
  1794. Now we define the
  1795. .cW stats
  1796. array:
  1797. .(C
  1798. * define function stats_in
  1799.       (language = "c", returntype = stats)
  1800.       arg is (char16)
  1801.       as "/usr/postgres/tutorial/stats.o" \\g
  1802.  
  1803. * define function stats_out
  1804.       (language = "c", returntype = char16)
  1805.       arg is (stats)
  1806.       as "/usr/postgres/tutorial/stats.o" \\g
  1807.  
  1808. * define type stats
  1809.       (element = int4, internallength = variable,
  1810.        input = stats_in, output = stats_out) \\g
  1811. .)C
  1812. Now we can run some queries:
  1813. .(C
  1814. * create test (a = quarterly, b = stats) \\g
  1815.  
  1816. * append test (a = "1 2 3 4"::quarterly,
  1817.                b = "5 6 7"::stats) \\g
  1818.  
  1819. * append test (a = "1 3 2 4"::quarterly,
  1820.                b = "6 4"::stats) \\g
  1821.  
  1822. * append test (a = "7 11 6 9"::quarterly,
  1823.                b = "1 2"::stats) \\g
  1824.  
  1825. * retrieve (test.all) where test.a[4] = test.b[2] \\g
  1826. .)C
  1827. which returns:
  1828. .(T
  1829. .TS
  1830. tab(|) allbox;
  1831. l l.
  1832. a|b
  1833. 1324|64
  1834. .TE
  1835. .)T
  1836. .b NOTE
  1837. that when you use your own functions to input and output array types,
  1838. .b "your function"
  1839. will define how to parse the external (string) representation.
  1840. The braces
  1841. notation is only a
  1842. convention used by
  1843. .cW array_in
  1844. and
  1845. .cW array_out
  1846. and is
  1847. .b not
  1848. part of the formal \*(PQ definition.
  1849. .\"------------------------------------
  1850. .sh 2 "Large Object types"
  1851. .lp
  1852. The types discussed to this point are all
  1853. .b small
  1854. objects\(emthat is, they are
  1855. smaller than 8 Kbytes\**
  1856. .(f
  1857. \**8 * 1,024 == 8,192 bytes
  1858. .)f
  1859. in size.
  1860. If you require a larger type for something like
  1861. a document retrieval system or for storing bitmaps, you will need to use
  1862. the \*(PP
  1863. .b "large object"
  1864. interface.
  1865. The interface to large objects is quite similar to the
  1866. \*(UU file system interface.
  1867. The particulars are detailed in
  1868. Section 7 of the \*(PP Reference Manual, which you should have available to
  1869. consult as you read the following.
  1870. .\"-----------------
  1871. .sh 3 "Defining a large object"
  1872. .lp
  1873. Just like any other type, a large object type requires input and output
  1874. functions.
  1875. For the purposes of this discussion, we assume that two functions,
  1876. .cW large_in
  1877. and
  1878. .cW large_out
  1879. have been written using the large object interface, and that the compiled
  1880. functions
  1881. are in
  1882. .cW /usr/postgres/tutorial/large.o .
  1883. We also presume that we are using
  1884. the
  1885. .q "file as an ADT"
  1886. interface for large objects discussed in the Reference
  1887. Manual.
  1888. .lp
  1889. We define a large object which could be used for storing map data:
  1890. .(C
  1891. * define function large_in
  1892.       (language = "c", returntype = map)
  1893.       arg is (char16)
  1894.       as "/usr/postgres/tutorial/large.o" \\g
  1895.  
  1896. * define function large_out
  1897.       (language = "c", returntype = char16)
  1898.       arg is (map)
  1899.       as "/usr/postgres/tutorial/large.o" \\g
  1900.  
  1901. * define type map
  1902.       (internallength = variable,
  1903.        input = large_in, output = large_out) \\g
  1904. .)C
  1905. Note that
  1906. large objects are
  1907. .b always
  1908. variable-length.
  1909. .lp
  1910. Now we can use our
  1911. .cW map
  1912. object:
  1913. .(C
  1914. * create maps (name = text, a = map) \\g
  1915.  
  1916. * append maps (name = "earth",
  1917.                a = "/usr/postgres/maps/earth") \\g
  1918.  
  1919. * append maps (name = "moon",
  1920.                a = "/usr/postgres/maps/moon") \\g
  1921. .)C
  1922. Notice that the above queries are identical in syntax to those we have been
  1923. using
  1924. all along to define types and such; the fact that this type is a large object
  1925. is completely hidden in the large object interface and \*(PP storage manager.
  1926. .\"-----------------
  1927. .sh 3 "Writing functions and operators for large object types"
  1928. .lp
  1929. Like any other \*(PP type, you can define functions and operators for large
  1930. object types.
  1931. The only caveat is that, like any other functions which process
  1932. a large object, they
  1933. .b must
  1934. use the large object interface described in Section 7 of the \*(PP Reference
  1935. Manual.
  1936. Possible queries which involve functions on large objects could include
  1937. .(C
  1938. * retrieve (emp.name) where beard(emp.picture) = "red" \\g
  1939.  
  1940. * retrieve (mountain.name)
  1941.       where height(mountain.topomap) > 10000 \\g
  1942. .)C
  1943. Because all functionality is available
  1944. to large objects,
  1945. .b any
  1946. aspect of \*(PP is available for use with them, including index access
  1947. methods, if the appropriate operator classes have been defined.
  1948. Operator
  1949. classes for index access methods will be discussed later in this manual.
  1950. .\"---------------------------------------------------------------------------
  1951. .sh 1 "The \*(PP Rule System"
  1952. .lp
  1953. The discussion in this section is intended to provide an overview of the
  1954. \*(PP rule system and point the user at helpful references and examples.
  1955. \*(PP actually has two rule systems, the
  1956. .b instance-level
  1957. rule system and the
  1958. .b "query rewrite"
  1959. rule system.
  1960. .\"------------------------------------
  1961. .sh 2 "The Instance-level Rule System"
  1962. .lp
  1963. The instance-level rule system uses markers placed in each instance in a
  1964. class to
  1965. .q trigger
  1966. rules.
  1967. Examples of the instance-level rule system are
  1968. explained and illustrated in
  1969. .cW $POSTGRESHOME/demo ,
  1970. which is included with the
  1971. \*(PP distribution.
  1972. Additional discussion of the instance-level rule system
  1973. can be found in the Reference Manual under
  1974. .cW "define rule" .
  1975. The theoretical
  1976. foundations
  1977. of the \*(PP rule system can be found in [STON90].
  1978. .\"------------------------------------
  1979. .sh 2 "The Query Rewrite Rule System"
  1980. .lp
  1981. The query rewrite rule system modifies queries to take rules into
  1982. consideration, and then passes the modified query to the query optimizer for
  1983. execution.
  1984. It is very powerful, and can be used for many things such as
  1985. query language procedures, views, and versions.
  1986. Examples and discussion can
  1987. be found in the demo in
  1988. .cW $POSTGRESHOME/video ,
  1989. and further discussion is in the
  1990. Reference Manual under
  1991. .cW "define rule" .
  1992. The power of this rule system is
  1993. discussed in
  1994. [ONG90] and [STON90].
  1995. .\"------------------------------------
  1996. .sh 2 "When to use either?"
  1997. .lp
  1998. Since each rule system is architected quite differently, they work best in
  1999. different situations.
  2000. The query rewrite system is best when rules affect
  2001. most of the instances in a class, while the instance-level system is best when
  2002. a rule affects only a few instances.
  2003. .\"---------------------------------------------------------------------------
  2004. .sh 1 "Administering \*(PP"
  2005. .lp
  2006. In this section, we will discuss aspects of \*(PP of interest to those
  2007. making extensive use of \*(PP, or who are the database administrator for
  2008. a group of \*(PP users.
  2009. .\"------------------------------------
  2010. .sh 2 "User administration"
  2011. .lp
  2012. The
  2013. .cW createuser
  2014. and
  2015. .cW destroyuser
  2016. enable and disable access to \*(PP by specific users on the host system.
  2017. Please read the descriptions of these
  2018. commands in the Reference Manual for specifics on their use.
  2019. .\"------------------------------------
  2020. .sh 2 "Moving database directories out of $POSTGRESHOME/data/base"
  2021. .lp
  2022. By default,
  2023. all \*(PP databases are stored in separate subdirectories under
  2024. .cW $POSTGRESHOME/data/base/ .\**
  2025. .(f
  2026. \**Data for certain classes may stored elsewhere if
  2027. a non-standard storage manager was specified
  2028. when they were created.
  2029. .)f
  2030. To move a particular data base to an alternate directory (e.g., on a
  2031. filesystem with more free space),
  2032. do the following:
  2033. .ip \(bu
  2034. Create the database
  2035. (if it doesn't already exist)
  2036. using the
  2037. .b createdb
  2038. command.
  2039. In the following steps
  2040. we will assume the database is named
  2041. .cW foo .
  2042. .ip \(bu
  2043. Copy
  2044. the directory
  2045. .cW $POSTGRESHOME/data/base/foo
  2046. and it contents
  2047. to its ultimate destination.
  2048. It should still be owned by the
  2049. .cW postgres
  2050. user.
  2051. .ip \(bu
  2052. Remove the directory
  2053. .cW $POSTGRESHOME/data/base/foo .
  2054. .ip \(bu
  2055. Make a symbolic link in
  2056. .cW $POSTGRESHOME/data/base
  2057. to the new directory.
  2058. .\"------------------------------------
  2059. .sh 2 "Troubleshooting \*(PP"
  2060. .lp
  2061. Occasionally, \*(PP will fail with cryptic error messages that are due to
  2062. relatively simple problems.
  2063. The following are a list of \*(PP error
  2064. messages and the likely fix.
  2065. These messages are ones you would likely see
  2066. in the
  2067. monitor
  2068. program.
  2069. .(C
  2070. Message: semget: No space left on device
  2071.  
  2072. Explanation and Likely Fix:
  2073. .)C
  2074. Either the kernel has not been configured for System V shared memory, or some
  2075. other program is using it up.
  2076. On most machines, the \*(UU command
  2077. .cW ipcs
  2078. will
  2079. show shared memory and semaphore usage.
  2080. .lp
  2081. To delete all shared memory and
  2082. semaphores (may be necessary if a backend fails), run the
  2083. .cW ipcclean
  2084. command.
  2085. Note, however, that
  2086. .cW ipcclean
  2087. deletes
  2088. .b all
  2089. semaphores belonging
  2090. to the user running it, so the user should be certain that none of his/her
  2091. non-\*(PP
  2092. processes are using semaphores before running this command.
  2093. .(C
  2094. Message: Unable to get shared buffers
  2095.  
  2096. Explanation and Likely Fix:
  2097. .)C
  2098. This message means that a \*(PP backend was expecting shared memory to be
  2099. available and it was not.
  2100. Usually this is due to
  2101. .cW ipcclean
  2102. being run while a
  2103. .cW postmaster
  2104. was also running.
  2105. .(C
  2106. Message: Can't connect to the backend (...)
  2107.  
  2108. Explanation and Likely Fix:
  2109. .)C
  2110. This message means that you are running a \*(LP application but it could
  2111. not link up with a
  2112. .cW postmaster .
  2113. If you see this error message, you should
  2114. see if a
  2115. .cW postmaster
  2116. is truly running.
  2117. If one is running, the problem is
  2118. likely related to your network.
  2119. .\"---------------------------------------------------------------------------
  2120. .sh 1 "REFERENCES"
  2121. .\"------------------------------------
  2122. .xP [ONG90]
  2123. Ong, L. and Goh, J.,
  2124. ``A Unified Framework for Version Modeling Using Production Rules in a Database
  2125. System,"
  2126. Electronics Research Laboratory,
  2127. University of California, Berkeley,
  2128. ERL Memo M90/33,
  2129. April 1990.
  2130. .\"------------------------------------
  2131. .xP [ROWE87]
  2132. Rowe, L. and Stonebraker, M.,
  2133. ``The POSTGRES Data Model,''
  2134. Proc. 1987 VLDB Conference,
  2135. Brighton, England,
  2136. Sept. 1987.
  2137. .\"------------------------------------
  2138. .xP [SCHA90]
  2139. Shapiro, L.,
  2140. ``Join Processing in Database Systems with Large Main Memories,''
  2141. ACM-TODS,
  2142. Sept. 1986.
  2143. .\"------------------------------------
  2144. .xP [STON86]
  2145. (missing)
  2146. .\"------------------------------------
  2147. .xP [STON87]
  2148. Stonebraker, M.,
  2149. ``The POSTGRES Storage System,''
  2150. Proc. 1987 VLDB Conference,
  2151. Brighton, England,
  2152. Sept. 1987.
  2153. .\"------------------------------------
  2154. .xP [STON88]
  2155. (missing)
  2156. .\"------------------------------------
  2157. .xP [STON90]
  2158. Stonebraker, M. et. al.,
  2159. ``On Rules, Procedures, Caching and Views in Database Systems,''
  2160. Proc. 1990 ACM-SIGMOD Conference on Management of Data,
  2161. Atlantic City, N.J.,
  2162. June 1990.
  2163. .\"------------------------------------
  2164. .xP [STON90B]
  2165. (missing)
  2166. .\"------------------------------------
  2167. .xP [WANG88]
  2168. (missing)
  2169. .\"---------------------------------------------------------------------------
  2170. .uh "APPENDIX: User defined types and indices"
  2171. .lp
  2172. In this section, we will discuss how to extend \*(PP to use a user-defined
  2173. type and associated functions with existing access methods.
  2174. This way, you
  2175. can define a BTREE or RTREE index on your own type.
  2176. To do this, we will
  2177. discuss how to define a new operator class in \*(PP
  2178. for use with an existing access method.
  2179. .lp
  2180. Our example will be to add a new operator class to the BTREE access method.
  2181. The new operator class will sort integers in ascending absolute value
  2182. order.
  2183. This tutorial will describe how to define the operator class.
  2184. If you work the example,
  2185. you will be able to define and use indices that sort integer
  2186. keys by absolute value.
  2187. .lp
  2188. There are several \*(PP system classes that are important in understanding how
  2189. the
  2190. access methods work.
  2191. These will be discussed, and then a sample procedure
  2192. for adding a new set of operators to an existing access method will be shown
  2193. as an example.
  2194. .lp
  2195. The
  2196. .cW pg_am
  2197. class contains one instance for every user defined access method.
  2198. Support for the HEAP access method is built into \*(PP,
  2199. but every other access method is described here.
  2200. The schema is
  2201. .TS
  2202. center tab(|);
  2203. lf(C)|l.
  2204. amname|name of the access method
  2205. _
  2206. amowner|object id of the owner's instance in pg_user
  2207. _
  2208. amkind|not used at present, but set to 'o' as a place holder
  2209. _
  2210. amstrategies|number of strategies for this access method (see below)
  2211. _
  2212. amsupport|number of support routines for this access method (see below)
  2213. _
  2214. am*|T{
  2215. procedure identifiers for interface
  2216. routines to the access method.
  2217. For
  2218. example,
  2219. .cW regproc
  2220. ids for opening, closing,
  2221. and getting instances from the access
  2222. method appear here.
  2223. T}
  2224. .TE
  2225. The object ID of the instance in
  2226. .cW pg_am
  2227. is used as a foreign key in lots of
  2228. other classes.
  2229. For BTREES, this object ID is 403.
  2230. You don't need to add
  2231. a new instance to this class; all you're interested in is the object ID of
  2232. the access method instance you want to extend:
  2233. .(C
  2234. * retrieve (pg_am.oid) where pg_am.amname = "btree" \\g
  2235. .TS
  2236. allbox;
  2237. l.
  2238. oid
  2239. 403
  2240. .TE
  2241. .)C
  2242. The
  2243. .cW amstrategies
  2244. attribute exists to standardize comparisons across data
  2245. types.
  2246. For example, BTREES impose a strict ordering on keys, less to
  2247. greater.
  2248. Since \*(PP allows the user to define operators, \*(PP cannot
  2249. in general look at the name of an operator (eg,
  2250. .cW > ,
  2251. .cW < )
  2252. and tell what kind
  2253. of comparison it is.
  2254. In fact, some access methods (like rtrees) don't impose
  2255. a less-to-greater ordering, but some other ordering, like containment.
  2256. \*(PP needs some consistent way of taking a scan qualification, looking at
  2257. the operator, deciding if a usable index exists, and rewriting the query
  2258. qualification in order to improve access speeds.
  2259. This implies
  2260. that \*(PP needs to know, for example, that
  2261. .cW <=
  2262. and
  2263. .cW >
  2264. partition
  2265. a BTREE.
  2266. Strategies is the way that we do this.
  2267. .lp
  2268. Defining a new set of strategies is beyond the scope of this discussion, but
  2269. how the BTREE strategies work will be explained, since you'll need to know that
  2270. to add a new operator class.
  2271. In the
  2272. .cW pg_am
  2273. class, the
  2274. .cW amstrategies
  2275. attribute is the number of strategies defined for this access method.
  2276. For BTREES, this
  2277. number is 5.
  2278. These strategies correspond to
  2279. .TS
  2280. center tab(|);
  2281. l|l.
  2282. less than|1
  2283. _
  2284. less than or equal|2
  2285. _
  2286. equal|3
  2287. _
  2288. greater than or equal|4
  2289. _
  2290. greater than|5
  2291. .TE
  2292. The idea is that you'll add procedures corresponding to the comparisons
  2293. above to the
  2294. .cW pg_amop
  2295. relation (see below).
  2296. The access method code can use
  2297. these numbers, regardless of data type, to figure out how to partition the
  2298. BTREE, compute selectivity, and so on.
  2299. Don't worry about the details of adding
  2300. procedures yet; just understand that there's a set of these for
  2301. .cW int2 ,
  2302. .cW int4 ,
  2303. .cW oid ,
  2304. and every other data type on which a BTREE can operate.
  2305. .lp
  2306. Strategies are used by all of the \*(PP access methods.
  2307. Some access methods require other support routines in order to work.
  2308. For example,
  2309. the BTREE access method must be able to compare two keys and determine
  2310. whether one is greater than, equal to, or less than the other.
  2311. Similarly,
  2312. the RTREE access method must be able to compute intersections,
  2313. unions,
  2314. and sizes of rectangles.
  2315. These operations do not correspond to user qualifications in
  2316. \*(PQ queries;
  2317. they are administrative routines used by the access methods,
  2318. internally.
  2319. .lp
  2320. In order to manage diverse support routines consistently across
  2321. all \*(PP access methods,
  2322. .cW pg_am
  2323. includes a field called
  2324. .cW amsupport .
  2325. This field records the number of support routines used by
  2326. an access method.
  2327. For BTREES, this number is one\(emthe routine to take two keys and return
  2328. \(mi\^1,
  2329. 0,
  2330. or
  2331. \(pl\^1,
  2332. depending on whether the first key is less than,
  2333. equal to,
  2334. or greater than the second.
  2335. .lp
  2336. The
  2337. .cW amstrategies
  2338. entry in
  2339. .cW pg_am
  2340. is just the number of strategies defined
  2341. for the access method in question.
  2342. The procedures for less than, less equal, and so on don't appear in
  2343. .cW pg_am .
  2344. Similarly,
  2345. .cW amsupport
  2346. is just the number of support routines required by the access method.
  2347. The actual routines are listed elsewhere.
  2348. .lp
  2349. The next class of interest is
  2350. .cW pg_opclass.
  2351. This class exists only to associate a name with an
  2352. .cW oid .
  2353. In
  2354. .cW pg_amop ,
  2355. every BTREE operator class has a set of procedures,
  2356. one through five, above.
  2357. Some existing opclasses are
  2358. .cW int2_ops ,
  2359. .cW int4_ops , and
  2360. .cW oid_ops .
  2361. You need to add an instance with your opclass name (for example,
  2362. .cW int4_abs_ops )
  2363. to
  2364. .cW pg_opclass .
  2365. The
  2366. .cW oid
  2367. of this instance is a foreign key in other classes.
  2368. .(C
  2369. * append pg_opclass (opcname = "int4_abs_ops") \\g
  2370.  
  2371. * retrieve (cl.oid, cl.opcname) from cl in pg_opclass
  2372.       where cl.opcname = "int4_abs_ops" \\g
  2373. .TS
  2374. tab(|) allbox;
  2375. l l.
  2376. oid|opcname
  2377. 17314|int4_abs_ops
  2378. .TE
  2379. .)C
  2380. .b NOTE:
  2381. The
  2382. .cW oid
  2383. for your
  2384. .cW pg_opclass
  2385. instance
  2386. .b "may be different" !
  2387. You should
  2388. substitute your value for 17314
  2389. wherever it appears in this discussion.
  2390. .lp
  2391. So now we have an access method and an operator class.
  2392. We still need a set of operators;
  2393. the procedure for defining operators was discussed earlier in this manual.
  2394. For the
  2395. .cW int4_abs_ops
  2396. operator class on BTREES,
  2397. the operators we require are:
  2398. .(l
  2399. absolute value less-than
  2400. absolute value less-than-or-equal
  2401. absolute value equal
  2402. absolute value greater-than-or-equal
  2403. absolute value greater-than
  2404. .)l
  2405. Suppose the code that implements the functions defined is stored in the file
  2406. .cW /usr/postgres/tutorial/int4_abs.c .
  2407. The code is
  2408. .(C
  2409. /*
  2410.  * int4_abs.c -- absolute value comparison functions
  2411.  *               for int4 data
  2412.  */
  2413.  
  2414. #include "tmp/c.h"
  2415.  
  2416. #define ABS(a) a = ((a < 0) ? -a : a)
  2417.  
  2418. bool int4_abs_lt(a, b) int32 a, b;
  2419.      { ABS(a); ABS(b); return (a < b); }
  2420.  
  2421. bool int4_abs_le(a, b) int32 a, b;
  2422.      { ABS(a); ABS(b); return (a <= b); }
  2423.  
  2424. bool int4_abs_eq(a, b) int32 a, b;
  2425.      { ABS(a); ABS(b); return (a == b); }
  2426.  
  2427. bool int4_abs_ge(a, b) int32 a, b;
  2428.      { ABS(a); ABS(b); return (a >= b); }
  2429.  
  2430. bool int4_abs_gt(a, b) int32 a, b;
  2431.      { ABS(a); ABS(b); return (a > b); }
  2432. .)C
  2433. There are a couple of important things that are happening below.
  2434. First, note that operators for less, less equal, equal, greater equal,
  2435. and greater for
  2436. .cW int4
  2437. are being defined.
  2438. All of these operators are already defined
  2439. for
  2440. .cW int4
  2441. under the names
  2442. .cW < ,
  2443. .cW <= ,
  2444. .cW = ,
  2445. .cW >= ,
  2446. and
  2447. .cW > .
  2448. The new operators behave differently, of course.
  2449. In order to guarantee that \*(PP uses
  2450. these new operators rather than the old ones,
  2451. they need to be named differently from the old ones.
  2452. This is a key point:  you can overload operators in
  2453. \*(PP, but only if the operator isn't already defined for the argument
  2454. types.
  2455. .lp
  2456. That is, if you have
  2457. .cW <
  2458. defined for
  2459. .cW int4 , (
  2460. .cW int4 ),
  2461. you can't define it again.
  2462. \*(PP
  2463. .b doesn't
  2464. check this when you define your operator,
  2465. so be careful.
  2466. To avoid this problem,
  2467. odd names will be used for the operators.
  2468. If you get this wrong,
  2469. the access methods are likely to crash when you try to do scans.
  2470. .lp
  2471. The other important point is that all the functions return
  2472. .b boolean
  2473. values;
  2474. the access methods rely on this fact.
  2475. .(C
  2476. * define function int4_abs_lt
  2477.       (language = "c", returntype = bool)
  2478.       arg is (int4, int4)
  2479.       as "/usr/postgres/tutorial/int4_abs.o" \\g
  2480.  
  2481. * define function int4_abs_le
  2482.       (language = "c", returntype = bool)
  2483.       arg is (int4, int4)
  2484.       as "/usr/postgres/tutorial/int4_abs.o" \\g
  2485.  
  2486. * define function int4_abs_eq
  2487.       (language = "c", returntype = bool)
  2488.       arg is (int4, int4)
  2489.       as "/usr/postgres/tutorial/int4_abs.o" \\g
  2490.  
  2491. * define function int4_abs_ge
  2492.       (language = "c", returntype = bool)
  2493.       arg is (int4, int4)
  2494.       as "/usr/postgres/tutorial/int4_abs.o" \\g
  2495.  
  2496. * define function int4_abs_gt
  2497.       (language = "c", returntype = bool)
  2498.       arg is (int4, int4)
  2499.       as "/usr/postgres/tutorial/int4_abs.o" \\g
  2500. .)C
  2501. Now define the operators that use them.
  2502. As noted,
  2503. the operator names must be unique for two
  2504. .cW int4
  2505. operands.
  2506. You can do a query on
  2507. .cW pg_operator :
  2508. .(C
  2509. * retrieve (pg_operator.all) \\g
  2510. .)C
  2511. to see if your name is taken for the types you want.
  2512. The important things here are the procedure
  2513. (which are the C functions defined above)
  2514. and the restriction and join selectivity functions.
  2515. You should just use the ones used below\(emnote that there are different such
  2516. functions for the less-than,
  2517. equal,
  2518. and greater-than cases.
  2519. These
  2520. .b must
  2521. be supplied,
  2522. or the access method will die when it tries to use the operator.
  2523. You should copy the names for
  2524. .cW restrict
  2525. and
  2526. .cW join ,
  2527. but use the procedure names you defined in the last step.
  2528. .(C
  2529. * define operator <<&
  2530.       (arg1 = int4, arg2 = int4, procedure=int4_abs_lt,
  2531.        associativity = left, restrict = intltsel,
  2532.        join = intltjoinsel) \\g
  2533.  
  2534. * define operator <=&
  2535.       (arg1 = int4, arg2 = int4, procedure = int4_abs_le,
  2536.        associativity = left, restrict = intltsel,
  2537.        join = intltjoinsel) \\g
  2538.  
  2539. * define operator ==&
  2540.       (arg1 = int4, arg2 = int4, procedure = int4_abs_eq,
  2541.        associativity = left, restrict = eqsel,
  2542.        join = eqjoinsel) \\g
  2543.  
  2544. * define operator >=&
  2545.       (arg1 = int4, arg2 = int4, procedure = int4_abs_ge,
  2546.        associativity = left, restrict = intgtsel,
  2547.        join = intgtjoinsel) \\g
  2548.  
  2549. * define operator >>&
  2550.       (arg1 = int4, arg2 = int4, procedure = int4_abs_gt,
  2551.        associativity = left, restrict = intgtsel,
  2552.        join = intgtjoinsel) \\g
  2553. .)C
  2554. Notice that five operators corresponding to less, less equal, equal, greater,
  2555. and greater equal are defined.
  2556. .lp
  2557. We're just about finished. the last thing we
  2558. need to do is to update the
  2559. .cW pg_amop
  2560. relation.
  2561. To do this, we need the
  2562. following attributes:
  2563. .TS
  2564. center tab(|);
  2565. lf(C)|l.
  2566. amopid|T{
  2567. the
  2568. .cW oid
  2569. of the
  2570. .cW pg_am
  2571. instance for BTREE (== 400, see above)
  2572. T}
  2573. _
  2574. amopclaid|T{
  2575. the
  2576. .cW oid
  2577. of the
  2578. .cW pg_opclass
  2579. instance for
  2580. .cW int4_abs_ops
  2581. (== whatever you got instead
  2582. of 17314,
  2583. see above)
  2584. T}
  2585. _
  2586. amopopr|T{
  2587. the
  2588. .cW oid s
  2589. of the operators for the
  2590. opclass (which we'll get in just a
  2591. minute)
  2592. T}
  2593. _
  2594. T{
  2595. amopselect,
  2596. .br
  2597. amopnpages
  2598. T}|cost functions.
  2599. .TE
  2600. The cost functions are used by the query optimizer to decide whether
  2601. or not to use a given index in a scan.
  2602. Fortunately, these already
  2603. exist.
  2604. The two functions we'll use are
  2605. .cW btreesel,
  2606. which estimates the
  2607. selectivity of the btree, and
  2608. .cW btreenpage,
  2609. which estimates the number of
  2610. pages a search will touch in the tree.
  2611. .lp
  2612. So we need the
  2613. .cW oid s
  2614. of the operators we just defined.
  2615. We'll look up the
  2616. names of all the operators that take two
  2617. .cW int4 s,
  2618. and pick ours out:
  2619. .(C
  2620. * retrieve (o.oid, o.oprname)
  2621.       from o in pg_operator, t in pg_type
  2622.       where o.oprleft = t.oid and o.oprright = t.oid
  2623.           and t.typname = "int4" \\g
  2624. .)C
  2625. which returns:
  2626. .(T
  2627. .TS
  2628. tab(|) allbox;
  2629. l l.
  2630. oid|oprname
  2631. 96|\\=
  2632. 97|<
  2633. 514|*
  2634. 518|!=
  2635. 521|>
  2636. 523|<=
  2637. 525|>=
  2638. 528|/
  2639. 530|%
  2640. 551|+
  2641. 555|-
  2642. 17321|<<&
  2643. 17322|<=&
  2644. 17323|==*
  2645. 17324|>=&
  2646. 17325|>>&
  2647. .TE
  2648. .)T
  2649. (Note
  2650. that your
  2651. .cW oid
  2652. numbers may be different.)
  2653. The operators we are interested in are those with
  2654. .cW oid s
  2655. 17321 through 17325.
  2656. The values you get will probably be different, and you should substitute
  2657. them for the values below.
  2658. We can look at the operator names and pick out the ones we just added.
  2659. (Of course, there are lots of other queries we could used to get the oids
  2660. we wanted.)
  2661. .lp
  2662. Now we're ready to update
  2663. .cW pg_amop
  2664. with our new operator class.
  2665. The most
  2666. important thing in this entire discussion is that the operators are
  2667. ordered, from less equal through greater equal, in
  2668. .cW pg_amop .
  2669. Recall that
  2670. the BTREE instance's
  2671. .cW oid
  2672. is 400
  2673. and
  2674. .cW int4_abs_ops
  2675. is
  2676. .cW oid
  2677. 17314.
  2678. Then we
  2679. add the instances we need:
  2680. .(C
  2681. * append pg_amop
  2682.       (amopid = "400"::oid,          /* btree oid        */
  2683.        amopclaid = "17314"::oid,     /* pg_opclass tuple */
  2684.        amopopr = "17321"::oid,       /* <<& tup oid      */
  2685.        amopstrategy = "1"::int2,     /* 1 is <<&         */
  2686.        amopselect = "btreesel"::regproc,
  2687.        amopnpages = "btreenpage"::regproc) \\g
  2688.  
  2689. * append pg_amop (amopid = "400"::oid,
  2690.                   amopclaid = "17314"::oid,
  2691.                   amopopr = "17322"::oid,
  2692.                   amopstrategy = "2"::int2,
  2693.                   amopselect = "btreesel"::regproc,
  2694.                   amopnpages = "btreenpage"::regproc) \\g
  2695.  
  2696. * append pg_amop (amopid = "400"::oid,
  2697.                   amopclaid = "17314"::oid,
  2698.                   amopopr = "17323"::oid,
  2699.                   amopstrategy = "3"::int2,
  2700.                   amopselect = "btreesel"::regproc,
  2701.                   amopnpages = "btreenpage"::regproc) \\g
  2702.  
  2703. * append pg_amop (amopid = "400"::oid,
  2704.                   amopclaid = "17314"::oid,
  2705.                   amopopr = "17324"::oid,
  2706.                   amopstrategy = "4"::int2,
  2707.                   amopselect = "btreesel"::regproc,
  2708.                   amopnpages = "btreenpage"::regproc) \\g
  2709.  
  2710. * append pg_amop (amopid = "400"::oid,
  2711.                   amopclaid = "17314"::oid,
  2712.                   amopopr = "17325"::oid,
  2713.                   amopstrategy = "5"::int2,
  2714.                   amopselect = "btreesel"::regproc,
  2715.                   amopnpages = "btreenpage"::regproc) \\g
  2716. .)C
  2717. NOTE the order:
  2718. .q less
  2719. is 1,
  2720. .q "less equal"
  2721. is 2,
  2722. .q equal
  2723. is 3,
  2724. .q "greater equal"
  2725. is 4,
  2726. and
  2727. .q greater
  2728. is 5.
  2729. .lp
  2730. Okay, now it's time to test the new opclass.
  2731. First we'll create and
  2732. populate a class:
  2733. .(C
  2734. * create pairs (name = char16, number = int4) \\g
  2735.  
  2736. * append pairs (name = "mike", number = -10000) \\g
  2737.  
  2738. * append pairs (name = "greg", number = 3000) \\g
  2739.  
  2740. * append pairs (name = "lay peng", number = 5000) \\g
  2741.  
  2742. * append pairs (name = "jeff", number = -2000) \\g
  2743.  
  2744. * append pairs (name = "mao", number = 7000) \\g
  2745.  
  2746. * append pairs (name = "cimarron", number = -3000) \\g
  2747.  
  2748. * retrieve (pairs.all) \\g
  2749. .TS
  2750. tab(|) allbox;
  2751. l l.
  2752. name|number
  2753. mike|-10000
  2754. greg|3000
  2755. lay peng|5000
  2756. jeff|-2000
  2757. mao|7000
  2758. cimarron|-3000
  2759. .TE
  2760. .)C
  2761. Okay, looks pretty random.
  2762. Define an index using the new opclass:
  2763. .(C
  2764. * define index pairsind on pairs
  2765.       using btree (number int4_abs_ops) \\g
  2766. .)C
  2767. Now run a query that doesn't use one of our new operators.
  2768. What we're
  2769. trying to do here is to run a query that
  2770. .b won't
  2771. use our index, so that
  2772. we can tell the difference when we see a query that
  2773. .b does
  2774. use the index.
  2775. This query won't use the index because the operator we use in the qualification
  2776. isn't one that appears in the list of strategies for our index.
  2777. .(C
  2778. * retrieve (pairs.all) where pairs.number < 9000 \\g
  2779. .TS
  2780. tab(|) allbox;
  2781. l l.
  2782. name|number
  2783. mike|-10000
  2784. greg|3000
  2785. lay peng|5000
  2786. jeff|-2000
  2787. mao|7000
  2788. cimarron|-3000
  2789. .TE
  2790. .)C
  2791. Yup, just as random; that didn't use the index.
  2792. Okay, let's run a query
  2793. that
  2794. .b does
  2795. use the index:
  2796. .(C
  2797. * retrieve (pairs.all) where pairs.number <<& 9000 \\g
  2798. .TS
  2799. tab(|) allbox;
  2800. l l.
  2801. name|number
  2802. jeff|-2000
  2803. cimarron|-3000
  2804. greg|3000
  2805. lay peng|5000
  2806. mao|7000
  2807. .TE
  2808. .)C
  2809. Note that the
  2810. .cW number
  2811. values are in order of increasing absolute value
  2812. (as they should be, since the index was used for this scan) and that
  2813. we got the right answer\(emthe instance for
  2814. .cW mike
  2815. doesn't appear, because \(mi10000 >=& 9000.
  2816.